-
Notifications
You must be signed in to change notification settings - Fork 7
VPLAY-12164 Http 404 for mpd while channel change #845
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev_sprint_25_2
Are you sure you want to change the base?
Conversation
Reason for change: Moving the Teardown operation before the mpd update release cause some delay and results in more Http 404 errors. Test Procedure: updated in ticket Risks: Low Signed-off-by: Anurag Krishnan <akrish513@cable.comcast.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR addresses HTTP 404 errors occurring during channel changes by moving the MPD downloader release operation to happen immediately after stream abstraction deletion, rather than waiting for the complete Stop() sequence to finish.
Changes:
- Added conditional MPD downloader release inside
TeardownStream()whendisableDownloadsis true - The early release prevents unnecessary MPD update requests that would fail with HTTP 404 during channel transitions
| // stop the mpd update immediately after Stream abstraction delete | ||
| if(mMPDDownloaderInstance != nullptr) | ||
| { | ||
| mMPDDownloaderInstance->Release(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this call be removed from other places since it is done here? I.e. from PrivateInstanceAAMP::detach() and PrivateInstanceAAMP::Stop()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 3 comments.
| if(mMPDDownloaderInstance != nullptr) | ||
| { | ||
| mMPDDownloaderInstance->Release(); |
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new code block accesses mMPDDownloaderInstance without holding mLock. While this appears consistent with similar patterns elsewhere in the codebase (e.g., Stop() at line 8091 and detach() at line 7110), consider whether explicit locking is needed here for thread safety. The Release() method has internal locking via mMPDDnldMutex, but the pointer access itself is not synchronized. If mMPDDownloaderInstance can be deleted or modified from another thread during teardown, this could lead to a race condition.
| if(mMPDDownloaderInstance != nullptr) | |
| { | |
| mMPDDownloaderInstance->Release(); | |
| AampMPDDownloader *mpdDownloader = NULL; | |
| lock.lock(); | |
| mpdDownloader = mMPDDownloaderInstance; | |
| lock.unlock(); | |
| if(mpdDownloader != NULL) | |
| { | |
| mpdDownloader->Release(); |
| if(disableDownloads) | ||
| { | ||
| // stop the mpd update immediately after Stream abstraction delete | ||
| if(mMPDDownloaderInstance != nullptr) | ||
| { | ||
| mMPDDownloaderInstance->Release(); | ||
| } | ||
| } |
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change introduces a potential double-call to mMPDDownloaderInstance->Release(). When TeardownStream(true, true) is called from Stop() (line 8088), this new code will call Release(), and then Stop() calls it again at line 8091-8094. While Release() is idempotent (protected by the mReleaseCalled flag), consider whether the duplicate call in Stop() should be removed to avoid confusion and make the cleanup flow clearer.
| if(disableDownloads) | |
| { | |
| // stop the mpd update immediately after Stream abstraction delete | |
| if(mMPDDownloaderInstance != nullptr) | |
| { | |
| mMPDDownloaderInstance->Release(); | |
| } | |
| } | |
| // Note: MPD downloader Release() is handled by the caller (e.g. Stop()) | |
| // to avoid duplicate Release() calls when TeardownStream(true, true) is | |
| // invoked from Stop(). |
| if(disableDownloads) | ||
| { | ||
| // stop the mpd update immediately after Stream abstraction delete | ||
| if(mMPDDownloaderInstance != nullptr) | ||
| { | ||
| mMPDDownloaderInstance->Release(); | ||
| } | ||
| } |
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code uses a raw pointer (mMPDDownloaderInstance) with manual lifecycle management (new at line 5628, SAFE_DELETE at line 8199). Consider refactoring to use a smart pointer (e.g., std::unique_ptr) to follow modern C++ RAII principles and improve memory safety. This would make ownership semantics clearer and eliminate the possibility of memory leaks.
6098e5f to
62d4beb
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 3 comments.
|
|
||
| if(disableDownloads) | ||
| { | ||
| // stop the mpd update immediately after Stream abstraction delete |
Copilot
AI
Jan 21, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment "stop the mpd update immediately after Stream abstraction delete" is copied from line 8104 in the Stop() function but doesn't explain the rationale for this specific placement.
The comment should clarify:
- Why the MPD downloader needs to be released at this point in TeardownStream
- How this placement helps reduce HTTP 404 errors during channel changes (as mentioned in the PR description)
- The relationship with the existing Release() call in Stop() at line 8107
This will help future maintainers understand the design decision and prevent accidental removal or duplication.
| // stop the mpd update immediately after Stream abstraction delete | |
| /* | |
| * DASH-specific teardown: explicitly stop MPD updates as soon as the | |
| * stream abstraction has been stopped/deleted. | |
| * | |
| * Rationale: | |
| * - When changing channels, the MPD downloader may still be running | |
| * background manifest refreshes based on the old stream abstraction | |
| * state (periods, adaptation sets, timelines, etc.). | |
| * - If the service reuses the same MPD URL for the new channel or if | |
| * the old MPD becomes invalid while those refreshes are still in | |
| * flight, the downloader can issue requests that no longer match | |
| * the server state, leading to transient HTTP 404s during channel | |
| * changes (as described in the PR). | |
| * | |
| * By releasing the MPD downloader here, immediately after | |
| * mpStreamAbstractionAAMP is torn down and only when downloads are | |
| * being disabled, we ensure that no further MPD refreshes are issued | |
| * based on stale stream state. | |
| * | |
| * Note: | |
| * - There is also a later mMPDDownloaderInstance->Release() call in | |
| * Stop() (line 8107) which serves as a final safety net / global | |
| * cleanup. | |
| * - This earlier Release() in TeardownStream is the intentional, | |
| * protocol-aware shutdown point required to avoid the 404 bursts | |
| * seen on rapid channel changes; the Stop()-level call must not be | |
| * treated as a replacement for this one. | |
| */ |
| if(disableDownloads) | ||
| { | ||
| // stop the mpd update immediately after Stream abstraction delete | ||
| if(mMPDDownloaderInstance != nullptr) | ||
| { | ||
| mMPDDownloaderInstance->Release(); | ||
| } | ||
| } |
Copilot
AI
Jan 21, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This new code path (calling mMPDDownloaderInstance->Release() inside TeardownStream when disableDownloads is true) lacks test coverage.
The existing TeardownStream tests in test/utests/tests/PrivAampTests/PrivAampTests.cpp (TeardownStreamTest, TeardownStreamTest_1, TeardownStreamTest_2) do not verify:
- That Release() is called when disableDownloads=true
- That Release() is NOT called when disableDownloads=false
- The interaction with mMPDDownloaderInstance being null vs non-null
Add test cases to verify this behavior, especially for the scenario described in the ticket (channel change causing HTTP 404 errors).
| if(disableDownloads) | ||
| { | ||
| // stop the mpd update immediately after Stream abstraction delete | ||
| if(mMPDDownloaderInstance != nullptr) | ||
| { | ||
| mMPDDownloaderInstance->Release(); | ||
| } | ||
| } |
Copilot
AI
Jan 21, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change introduces a potential duplicate Release() call when TeardownStream is invoked from the Stop() function. At line 8102, Stop() calls TeardownStream(true, true) with disableDownloads=true, which will trigger this new Release() call. Then at line 8107, Stop() calls mMPDDownloaderInstance->Release() again.
While Release() is idempotent (protected by the mReleaseCalled flag), this duplication suggests a design issue. Consider one of the following solutions:
- Remove the Release() call at line 8107 in Stop() since it's now handled in TeardownStream
- Remove this new code and keep the existing Release() call in Stop() at line 8107
- Add a clear comment explaining why Release() is called in both locations if both are truly needed
The PR description mentions "Moving the Teardown operation before the mpd update release cause some delay" which suggests option 1 (removing the call from Stop()) may be the intended solution.
| if(disableDownloads) | |
| { | |
| // stop the mpd update immediately after Stream abstraction delete | |
| if(mMPDDownloaderInstance != nullptr) | |
| { | |
| mMPDDownloaderInstance->Release(); | |
| } | |
| } |
Reason for change: Moving the Teardown operation before the mpd update release cause some delay and results in more Http 404 errors.
Test Procedure: updated in ticket
Risks: Low